package com.yskj.mwk.utils;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yl.jms.sdk.auth.ClientConfiguration;
import com.yl.jms.sdk.client.JtExpressApiOperator;
import com.yl.jms.sdk.JtExpressApi;
import com.yskj.mwk.bean.Logistics;
import com.yskj.mwk.bean.Order;
import com.yskj.mwk.dao.ManagerMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 对接极兔物流
 * */
@Component
@Slf4j
public class JiTuUtil {

    private final ManagerMapper managerMapper;

    @Autowired // 构造器注入
    public JiTuUtil(ManagerMapper managerMapper) {
        this.managerMapper = managerMapper;
    }

    public static final String addOrderUrl = "https://uat-openapi.jtexpress.com.cn/webopenplatformapi/api/order/addOrder";
    public static final String printOrder ="https://uat-openapi.jtexpress.com.cn/webopenplatformapi/api/order/printOrder";
    public static final String cancelOrder ="https://uat-openapi.jtexpress.com.cn/webopenplatformapi/api/order/cancelOrder";
    public static final String trace ="https://uat-openapi.jtexpress.com.cn/webopenplatformapi/api/logistics/trace";

//    public static final String addOrderUrl = "https://openapi.jtexpress.com.cn/webopenplatformapi/api/order/addOrder";
//    public static final String printOrder ="https://openapi.jtexpress.com.cn/webopenplatformapi/api/order/printOrder";
//    public static final String cancelOrder ="https://openapi.jtexpress.com.cn/webopenplatformapi/api/order/cancelOrder";
//    public static final String trace ="https://openapi.jtexpress.com.cn/webopenplatformapi/api/logistics/trace";

    /***
     * 101，没有配置物流
     * 102,入库失败
     *
     * */
    public int addOrder(String orderId,int supplierId,String wlOrderId){
        //先获取租户的物流信息
        Logistics logistics=managerMapper.getLogisticsById(supplierId);
        if(logistics==null){
            //用户无配置物流信息
            log.error("【创建物流订单】租户未配置物流账号，租户编号：{}" , supplierId);
            return 101;
        }else {
            Map<String, Object> map = new HashMap<>();
            Map<String, Object> sender = new HashMap<>();
            Map<String, Object> receiver = new HashMap<>();
            map.put("txlogisticId", wlOrderId);
            map.put("expressType", "EZ");
            map.put("orderType", "2");
            map.put("serviceType", "01");
            map.put("deliveryType", "03");
            map.put("payType", "PP_PM");
            map.put("goodsType", "bm000006");
            map.put("weight", "1");

            sender.put("name", logistics.getSendName());
            sender.put("mobile", logistics.getSendTell());
            sender.put("phone", "");
            sender.put("countryCode", "CHN");
            sender.put("prov", logistics.getSendProv());
            sender.put("city", logistics.getSendCity());
            sender.put("area", logistics.getSendArea());
            sender.put("address", logistics.getSendProv()+logistics.getSendCity()+logistics.getSendArea()+logistics.getSendAddress());
            map.put("sender", sender);
            Order order=managerMapper.getOrderById(orderId);
            receiver.put("name", order.getReceiveName());
            receiver.put("mobile", order.getReceiveTell());
            receiver.put("phone", "");
            receiver.put("countryCode", "CHN");
            receiver.put("prov", order.getProv());
            receiver.put("city", order.getCity());
            receiver.put("area", order.getArea());
            receiver.put("address", order.getReceiveAddress());
            map.put("receiver", receiver);

            try{
                ObjectMapper objectMapper = new ObjectMapper();
                String json = objectMapper.writeValueAsString(map);
                log.info("【创建物流订单信息】:" + json);
                System.out.println(json);
                //创建授权用户实体
                ClientConfiguration clientConfiguration = new ClientConfiguration(logistics.getJt_apiAccount(), logistics.getJt_privateKey());
                //当调用postByCustom方法时需要customerCode和orderPassword
                clientConfiguration.setCustomerCode(logistics.getJt_customerCode());
                clientConfiguration.setCustomerPwd(logistics.getJt_orderPassword());
                JtExpressApi jtExpressApi = new JtExpressApiOperator(clientConfiguration);
                JSONObject location = jtExpressApi.postByCustom(map, addOrderUrl);
                log.info("【创建物流订单应答】:" + location);
                System.out.println(location);
                if (location.get("msg").equals("success")&& location.containsKey("data") && location.getJSONObject("data").containsKey("billCode")) {
                    String createTime= DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss");
                    String billCode = location.getJSONObject("data").getString("billCode");
                    int res=managerMapper.fahuo(orderId,billCode,createTime,3,wlOrderId);
                    if(res==1){
                        return 0;
                    }else{
                        return 102;
                    }
                }else{
                    return location.getInteger("code");
                }
            }catch (Exception e){
                e.printStackTrace();
                return 103;
            }
        }
    }

    //打印电子单
    public int printOrder(String orderId,String billCode,int supplierId,String url){
        Logistics logistics=managerMapper.getLogisticsById(supplierId);
        if(logistics==null){
            //用户无配置物流信息
            return 101;
        }else {
            Map<String, Object> map = new HashMap<>();
            map.put("billCode", billCode);

            log.info("【打印电子面单请求信息】:" + map);
            try {
                //创建授权用户实体
                ClientConfiguration clientConfiguration = new ClientConfiguration(logistics.getJt_apiAccount(), logistics.getJt_privateKey());
                //当调用postByCustom方法时需要customerCode和orderPassword
                clientConfiguration.setCustomerCode(logistics.getJt_customerCode());
                clientConfiguration.setCustomerPwd(logistics.getJt_orderPassword());
                JtExpressApi jtExpressApi = new JtExpressApiOperator(clientConfiguration);
                JSONObject location = jtExpressApi.postByCustom(map, printOrder);
                log.info("【打印电子面单应答状态】:{}; 状态码：{}" , location.get("msg"),location.get("code"));
                System.out.println(location.get("msg"));
                if (location.get("msg").equals("success") && location.containsKey("data") && location.getJSONObject("data").containsKey("base64EncodeContent")) {
                    String base64EncodeContent = location.getJSONObject("data").getString("base64EncodeContent");
                    log.info("【打印电子面单运单号】:{}" , location.getJSONObject("data").getString("billCode"));
                    // 1. 获取 Base64 解码器
                    Base64.Decoder decoder = Base64.getDecoder();

                    // 2. 解码 Base64 字符串为字节数组
                    byte[] decodedBytes = decoder.decode(base64EncodeContent);
                    //3.1 判断文件夹是否存在，不存在则创建
                    String pdfDirPath = "./upload/wuliu/";
                    File pdfDir = new File(pdfDirPath);
                    if (!pdfDir.exists()){
                        pdfDir.mkdirs();
                    }
                    String pdfPath=pdfDirPath+billCode+".pdf";
                    Files.write(Paths.get(pdfPath), decodedBytes);
                    //4.1 正则匹配请求前缀
                    Pattern pattern = Pattern.compile("(.*)/userApi/.*");
                    Matcher matcher = pattern.matcher(url);

                    String urlPrefix = "http://localhost:18080";

                    while(matcher.find()){
                        urlPrefix = matcher.group(1);
                    }
                    String pdfUrl=urlPrefix + "/wuliu/" + billCode+".pdf";
                    return managerMapper.setPrintPic(orderId,pdfUrl);
                } else {
                    log.info("【打印电子面单应答状态】:{}" , location);
                    return location.getInteger("code");
                }
            }catch (Exception e){
                // 记录错误日志（带堆栈）
                log.error("解码异常，路径: {}", "", e);
                return 103;
            }
        }
    }
    /**
     * 返回运单文件
     * */
    public String getPrintOrder(String orderId,String billCode,int supplierId,String url){
        Logistics logistics=managerMapper.getLogisticsById(supplierId);
        if(logistics==null){
            //用户无配置物流信息
            return null;
        }else {
            Map<String, Object> map = new HashMap<>();
            map.put("billCode", billCode);

            log.info("【打印电子面单请求信息】:" + map);
            try {
                //创建授权用户实体
                ClientConfiguration clientConfiguration = new ClientConfiguration(logistics.getJt_apiAccount(), logistics.getJt_privateKey());
                //当调用postByCustom方法时需要customerCode和orderPassword
                clientConfiguration.setCustomerCode(logistics.getJt_customerCode());
                clientConfiguration.setCustomerPwd(logistics.getJt_orderPassword());
                JtExpressApi jtExpressApi = new JtExpressApiOperator(clientConfiguration);
                JSONObject location = jtExpressApi.postByCustom(map, printOrder);
                log.info("【打印电子面单应答状态】:{}; 状态码：{}" , location.get("msg"),location.get("code"));
                System.out.println(location.get("msg"));
                if (location.get("msg").equals("success") && location.containsKey("data") && location.getJSONObject("data").containsKey("base64EncodeContent")) {
                    String base64EncodeContent = location.getJSONObject("data").getString("base64EncodeContent");
                    log.info("【打印电子面单运单号】:{}" , location.getJSONObject("data").getString("billCode"));
                    // 1. 获取 Base64 解码器
                    Base64.Decoder decoder = Base64.getDecoder();

                    // 2. 解码 Base64 字符串为字节数组
                    byte[] decodedBytes = decoder.decode(base64EncodeContent);
                    //3.1 判断文件夹是否存在，不存在则创建
                    String pdfDirPath = "./upload/wuliu/";
                    File pdfDir = new File(pdfDirPath);
                    if (!pdfDir.exists()){
                        pdfDir.mkdirs();
                    }
                    String pdfPath=pdfDirPath+billCode+".pdf";
                    Files.write(Paths.get(pdfPath), decodedBytes);
                    //4.1 正则匹配请求前缀
                    Pattern pattern = Pattern.compile("(.*)/manager/.*");
                    Matcher matcher = pattern.matcher(url);

                    String urlPrefix = "http://localhost:18080";

                    while(matcher.find()){
                        urlPrefix = matcher.group(1);
                    }
                    String pdfUrl=urlPrefix + "/wuliu/" + billCode+".pdf";
                    String createTime= DateUtil.format(DateUtil.date(), "yyyy-MM-dd HH:mm:ss");
                    managerMapper.setPrintPic2(orderId,pdfUrl,createTime);
                    return pdfUrl;
                } else {
                    log.info("【打印电子面单应答状态】:{}" , location);
                    return null;
                }
            }catch (Exception e){
                // 记录错误日志（带堆栈）
                log.error("解码异常，路径: {}", "", e);
                return null;
            }
        }
    }

    //取消订单
    public int cancelOrder(String orderId,int supplierId,String wlOrderId){
        Logistics logistics=managerMapper.getLogisticsById(supplierId);
        if(logistics==null){
            //用户无配置物流信息
            return 101;
        }else {
            Map<String, Object> map = new HashMap<>();
            map.put("orderType", 2);
            map.put("txlogisticId", wlOrderId);
            map.put("reason", "商品尚未准备，取消订单");
            log.info("【取消物流订单】请求体:{}" , map);
            try {
                //创建授权用户实体
                ClientConfiguration clientConfiguration = new ClientConfiguration(logistics.getJt_apiAccount(), logistics.getJt_privateKey());
                //当调用postByCustom方法时需要customerCode和orderPassword
                clientConfiguration.setCustomerCode(logistics.getJt_customerCode());
                clientConfiguration.setCustomerPwd(logistics.getJt_orderPassword());
                JtExpressApi jtExpressApi = new JtExpressApiOperator(clientConfiguration);
                JSONObject location = jtExpressApi.postByCustom(map, cancelOrder);
                log.info("【取消物流订单】应答消息:{}" , location);
                System.out.println(location);
                if (location.get("msg").equals("success")) {
                    int res=managerMapper.quxiaofahuo(orderId);
                    if (res == 1) {
                        return 0;
                    } else {
                        return 102;
                    }
                } else {
                    return location.getInteger("code");
                }
            }catch (Exception e){
                return 103;
            }
        }
    }

    //查询轨迹
    public String queryTrajectory(String billCode,int supplierId){
        Logistics logistics=managerMapper.getLogisticsById(supplierId);
        if(logistics==null){
            //用户无配置物流信息
            return "101";
        }else {
            Map<String, Object> map = new HashMap<>();
            map.put("billCodes", billCode);
            try {
                //创建授权用户实体
                ClientConfiguration clientConfiguration = new ClientConfiguration(logistics.getJt_apiAccount(), logistics.getJt_privateKey());
                //当调用postByCustom方法时需要customerCode和orderPassword
                clientConfiguration.setCustomerCode(logistics.getJt_customerCode());
                clientConfiguration.setCustomerPwd(logistics.getJt_orderPassword());
                JtExpressApi jtExpressApi = new JtExpressApiOperator(clientConfiguration);
                JSONObject location = jtExpressApi.postByCustom(map, trace);
                System.out.println(location);
                if (location.get("msg").equals("success")) {
                    return location.get("data").toString();
                } else {
                    return location.getInteger("code")+"";
                }
            }catch (Exception e){
                return "103";
            }
        }
    }

}
